<template>
  <div>
    <!-- 使用list-type 可以设置组件的样式 -->
    <!-- action 代表的是上传图片的服务地址，这里用#防止控制台报错 -->
    <!-- limit 上传图片的数量 -->
    <!-- on-preview 点击图片预览的时候会触发这个事件 -->
    <!-- file-list 代表的是 上传文件列表，图片上传成功的地址会存在这里 -->
    <!-- 通过动态class控制上传组件的展示隐藏 -->
    <el-upload
      :class="{ isShow: fileComputed }"
      list-type="picture-card"
      :limit="1"
      action="#"
      :file-list="fileList"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :on-change="changeFile"
      :before-upload="beforeUpload"
      :http-request="upload"
    >
      <i class="el-icon-plus"></i>
    </el-upload>
    <!--  -->
    <el-progress v-if="showPercent" :percentage="percent" style="width:180px" />
    <!-- 准备预览图片的弹层 -->
    <el-dialog :visible.sync="showDialog" title="图片预览">
      <img :src="imgUrl" style="width: 100%" />
    </el-dialog>
  </div>
</template>

<script>
import COS from 'cos-js-sdk-v5'
const cos = new COS({
  SecretId: 'AKIDbJq9GD0hwAvUr45starzudDgDo260gAT', // 身份识别id
  SecretKey: 'CB0gEdqsjQvGKG2d2FIJ9cu19GLoFYXL' // 身份秘钥
})
export default {
  data() {
    return {
      fileList: [],
      imgUrl: '',
      showDialog: false,
      currentFileUid: '',
      percent: 0,
      showPercent: false
    }
  },
  computed: {
    // 计算属性的变量，如果fileList 里面有一张图片，则会返回true,图片上传组件隐藏，否则上传组件显示
    fileComputed() {
      return this.fileList.length === 1
    }
  },
  methods: {
    // 点击加号会触发图片预览事件，拿到图片的url
    handlePreview(file) {
      // flie参数 拿到的是预览图片的信息
      console.log(file)
      this.imgUrl = file.url
      this.showDialog = true
    },
    // 移除图片的钩子函数
    handleRemove(file, fileList) {
      // file 参数代表的是删除的图片信息，主要包括删除图片的uid 和图片的url
      // fileList 代表的是将存放图片列表的数组进行了一个返回
      console.log(file)
      // console.log(fileList)
      // 第一种删除方式：直接将删除后的filelist 赋值给flieList
      // this.fileList = fileList
      // 第二种删除方式：通过数组的filter方法将自己排除在外，相当于fileList 里面没有了自己，等于间接性删除
      // console.log(this.fileList)
      this.fileList = this.fileList.filter((item) => item.uid !== file.uid)
    },
    // 添加文件的方法
    changeFile(file, fileList) {
      // 事件触发了两次，图片选择完后触发，图片上传成功或失败也会触发一次
      // 图片还没有上传成功，fileList还是一个空数组
      // console.log(file)
      console.log(fileList, 333)
      this.fileList = fileList.map((item) => item)
    },
    // 文件上传之前的钩子函数
    beforeUpload(file) {
      // file 是一个对象，在里面可以拿到要上传图片的大小及格式
      console.log(file)
      // 文件类型 文件大小
      const types = ['image/jpeg', 'image/gif', 'image/bmp', 'image/png']
      if (!types.includes(file.type)) {
        this.$message.error('上传图片只能是 JPG、GIF、BMP、PNG 格式!')
        return false
      }
      // 对图片的大小进行判断
      const maxSize = 5 * 1024 * 1024
      if (maxSize < file.size) {
        this.$message.warning('上传图片的大小最大为5M')
        return false
      }
      // 如果都符合要求返回true
      // 将要上传的uid 做一个记录
      this.currentFileUid = file.uid
      this.showPercent = true // 在图片上传之前开启进度条的展示
      return true
    },
    // 选择图片完成之后，执行自定义上传方法
    upload(params) {
      console.log(params)
      // 在上传文件之前判断如果这个文件存在，则调用cos方法
      if (params.file) {
        cos.putObject({
          Bucket: 'szl-1314168906', /* 填入您自己的存储桶，必须字段 */
          Region: 'ap-beijing', /* 存储桶所在地域，例如ap-beijing，必须字段 */
          Key: params.file.name, // 以文件名称为key 值
          StorageClass: 'STANDARD',
          Body: params.file, // 上传文件对象
          onProgress: (params) => {
            // params 里面有一个percent代表上传的进度
            this.percent = params.percent * 100
            console.log(params)
          }
          // 这里需要改成箭头函数，this才能指出去
        }, (err, data) => {
          // 如果成功则会拿到data,里面包含成功之后的url地址
          console.log(err || data)
          // 没有err 且状态码是200的时候证明图片上传成功了
          if (!err && data.statusCode === 200) {
            // 第一种直接采取赋值, 只有一张图片的时候才可以这样写
            // this.fileList = [{ url: `http://${data.Location}` }]
            // 第二种： flieList 是一个数组，里面可能会有多个对象，不能直接采取赋值
            this.fileList = this.fileList.map(item => {
              if (item.uid === this.currentFileUid) {
                return { url: `http://${data.Location}`, upload: true }
                // 如果上传之前的记录的uid和选择完毕执行上传操作之后的UID相等，那么将上传成功之后的地址赋值给这个对象
              } else {
                // 如果不相等，则原地返回
                return item
              }
              // 最后将map之后的结果返回到一个新数组里面
              // 考虑到图片大小不同，上传速度不同，有些图片上传比较慢，为了防止在没上传成功的时候点击保存按钮，我们需要加一个上传成功之后的标识
            })
            // 图片上传成功之后，需要关闭进度条加一个定时延时器隐藏
            setTimeout(() => {
              this.showPercent = false // 关闭进度条
              this.percent = 0
            }, 1000)
          }
        })
      }
    }
  }
}
</script>

<style lang="scss">
.isShow {
  .el-upload--picture-card {
    display: none;
  }
}
// .isShow .el-upload--picture-card {
//   display: none;
// }
</style>
